import React, { useState, useEffect } from "react";


// 副作用函数
export const TestEffect: React.FC = () => {
    const [count, setCount] = useState(0);
    const addCount = () => {
        setCount(e => {
            return e + 1
        })
    }
    // useEffect  在组件第一次渲染时 一定会执行一次！！！！

    // 第一种：useEffect 中第二个参数 为空 的情况 ：表示每次执行rerender方法都会渲染执行 useEffect
    // useEffect(() => {
    //     console.log("useEffect");
    // });

    // 第二种情况：useEffect 中第二个参数 为空数组：表示只会在组件第一次渲染的时候执行一次，其他rerender方法的时候都不会执行；
    //  useEffect(()=>{
    //     console.log("useEffect");
    // },[]);

    // 第三种情况：useEffect 中第二个参数为 数组并且，其中有一个或者多个值；表示只有在 数组中的值 发生变化时 才会执行useEffect
    useEffect(() => {
        console.log("useEffect");
    }, [count]);



    return (
        <>
            <h1>TestEffect </h1>
            <p>{count}</p>
            <button onClick={addCount}>+1</button>

        </>
    )
}


// useEffect如何清理 副作用函数  A：去除页面监听；B：终止取消服务请求

export const SonEffect: React.FC = () => {
    // 1，记录鼠标位置信息
    const [postionObj, setPostionObj] = useState({ x: 0, y: 0 });

    useEffect(() => {
        const fn = (e: MouseEvent) => {
            setPostionObj({ x: e.clientX, y: e.clientY });
        }
        // 2.组件首次渲染完毕后，为window对象绑定mouseMove事件
        window.addEventListener("mousemove", fn)




        // 3.返回一个清理的函数，在每次组件卸载时，为window对象解绑mousemove事件；
        return () => {
            // 清理副作用函数的2个执行点：
            // 1.当组件被销毁时执行；
            window.removeEventListener("mousemove", fn)
            console.log("清理副作用函数")
        }
    }, [])
    return (
        <>
            <h1>鼠标位置{JSON.stringify(postionObj)}</h1>
        </>
    )
}

export const TestEffect2: React.FC = () => {
    const [flag, setFlag] = useState(true);
    return (
        <>
            {/* 现在需要页面启动就监听鼠标位置，点击切换，关闭监听，再次点击 启动监听 */}
            <button onClick={() => setFlag(e => !e)}>切换</button>
            {flag && <SonEffect />}
        </>
    )
}


// 第二种情况
// 终止请求
export const ColorSon: React.FC = () => {
    const [color, setColor] = useState("red");
    const diyStyle = {
        color:'#000',
        with:100,
        height:100,
        backgroundColor:color
    }
    useEffect(()=>{
        // 为了让请求可以终止，需要实例化一个 abortController；
        const controller = new AbortController();
        // console.log(controller)
        // 请求接口
        fetch("https://api.liulongbin.top/v1/color",{signal:controller.signal})
        .then(res=>res.json())
        .then(res=>{
            console.log(res)
            setColor(res.data.color)
        }).catch(err=>{
            console.log(err);

        })
        // 通过清理副作用函数来 实现 中断请求
        return()=>{
            // 终止请求
            controller.abort();
        }
    },[])
    return (
        <>
            <div style={diyStyle}>默认背景颜色为红色，正在请求颜色中...</div>
        </>
    )
}

export const ColorBox: React.FC = () => {
    const [flag, setFlag] = useState(true);
    return (
        <>
            <button onClick={() => setFlag(() => !flag)}>切换</button>

            {flag && <ColorSon />}
        </>
    )
}

